How ModularCounter method calls work with Inheritance (nf) : (not found), check higher base class in inheritance hierarchy self/m : self parameter in method name (actually bound to m) ------------------------------------------------------------------------------ m = Modular_Counter(2,10) Call m.reset() FEOOP Modular_Counter.reset(m) (nf)Inheritance Counter.reset(m) Method Body self/m._value = 0 m._value is now 0 ------------------------------------------------------------------------------ m = Modular_Counter(2,10) # inc calls Counter.inc Call m.inc() FEOOP Modular_Counter.inc(m) Method Body (if test) self/m.value_of() FEOOP Modular_Counter.value_of(self/m) (nf) Inheritance Counter.value_of(self/m) Method Body return self/m._value (2) Method Body (if) compares (2) == self._modulus -1 (False, in if) Body if (False part) Counter.inc(self/m) Method Body self/m._value += 1 m._value is now 3 ------------------------------------------------------------------------------ m = Modular_Counter(9,10) # inc calls reset Call m.inc() FEOOP Modular_Counter.inc(m) Method Body (if) self/m.value_of() FEOOP Modular_Counter.value_of(self/m) (nf) Inheritance Counter.value_of(self/m) Method Body return self/m._value (9) Method Body (if) compares (9) == self._modulus -1 (True, in if) Body of if (True part) self/m.reset() FEOOP Modular_Counter.reset(self/m) (nf) Inheritance Counter.reset(self/m) Method Body self/m._value = 0 m._value is now 0 ------------------------------------------------------------------------------ Just the "interesting parts" (used above) of these classes. See lecture note for all details. class Counter: ... def reset(self): # NOT overridden in Modular_Counter self._value = 0 def inc(self): # Overridden self._value += 1 def value_of(self): # NOT overridden in Modular_Counter return self._value class Modular_Counter(Counter): ... def inc(self): if self.value_of() == self._modulus - 1: self.reset() else: Counter.inc(self)